/*----------------------------------------------------------------------
* Copyright (C) 2013 - 2014: Sergey Smolyannikov <brainstream@yandex.com>
*
* This file is part of lxpamon.
*
* lxpamon is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lxpamon is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lxpamon. If not, see http://www.gnu.org/licenses/gpl-3.0.txt.
----------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <glib.h>
#include "pamon.h"
#include "utils.h"

#define APP_NAME "pamon"
#define DEFAULT_FORMAT "%i%%"
#define ALLOWED_FORMAT "i"
#define INVALID_FORMAT_SYMBOL '?'

typedef struct
{
    char * format;
    uint32_t sink;
    int print_help;
} Options;

static void pamonVolumeChanged(uint32_t current_volume, void * userdata);
static void pamonError(PamonError error, void * userdata);
static void onSignal(int signum);
static void parseOpts(int argc, char ** argv, Options * result);
static void printUsage();

static Pamon * pamon = NULL;
static GMainLoop * main_loop = NULL;
static char * format = NULL;


int main(int argc, char ** argv)
{
    struct sigaction action;
    memset(&action, 0, sizeof(struct sigaction));
    action.sa_handler = onSignal;
    sigaction(SIGINT, &action, NULL);
    PamonInitData pamon_init_data;
    memset(&pamon_init_data, 0, sizeof(PamonInitData));
    {
        Options opts;
        memset(&opts, 0, sizeof(Options));
        parseOpts(argc, argv, &opts);
        if(opts.print_help)
        {
            printUsage();
            free(opts.format);
            return EXIT_SUCCESS;
        }
        pamon_init_data.sink_id = opts.sink;
        format = fixPrintfTemplatePlaceholderOccurences(opts.format, ALLOWED_FORMAT, INVALID_FORMAT_SYMBOL);
    }
    pamon_init_data.volume_callback = pamonVolumeChanged;
    pamon_init_data.error_callback = pamonError;
    main_loop = g_main_loop_new(NULL, FALSE);
    pamon = pamonInit(&pamon_init_data);
    g_main_loop_run(main_loop);
    return EXIT_SUCCESS;
}

void onSignal(int signum)
{
    pamonClose(pamon);
    g_main_loop_quit(main_loop);
    g_main_loop_unref(main_loop);
    free(format);
    printf("\nquit\n");
    exit(EXIT_SUCCESS);
}

void pamonVolumeChanged(uint32_t current_volume, void * userdata)
{
    PAMON_UNUSED(userdata);
    printf(format ? format : DEFAULT_FORMAT, current_volume);
    printf("\n");
    fflush(stdout);
}

void pamonError(PamonError error, void * userdata)
{
    PAMON_UNUSED(userdata);
    fprintf(stderr, "Error: %s\n", pamonTranslateError(error));
}

void parseOpts(int argc, char ** argv, Options * result)
{
    for(;;)
    {
        switch(getopt(argc, argv, "f:s:")) 
        {
        case -1:
            return;
        case '?':
            result->print_help = 1;
            break;
        case 'f':
            result->format = (char *)malloc(strlen(optarg) + 1);
            strcpy(result->format, optarg);
            break;
        case 's':
            sscanf(optarg, "%i", &result->sink);
            break;
        default:
            break;
        }
    }
}

void printUsage()
{
    printf(
        "Usage: %s [-s sink] [-f format]\n"
        "    sink   - pulseaudio sink id\n"
        "    format - print format. Use %%i to print current volume value. Use %%%% to print the %% mark\n"
        "\n"
        "Use Ctrl+C to exit program\n",
        APP_NAME);
    fflush(stdout);
}
